package com.lyf.scm.admin.domain.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageInfo;
import com.lyf.scm.admin.api.dto.DateLabelDTO;
import com.lyf.scm.admin.domain.remote.basedata.dto.*;
import com.lyf.scm.admin.domain.remote.basedata.facade.BaseDataFacade;
import com.lyf.scm.admin.domain.remote.item.dto.CategoryBaseInfoDTO;
import com.lyf.scm.admin.domain.remote.item.dto.SkuInfoDTO;
import com.lyf.scm.admin.domain.remote.item.dto.UnitTypeDTO;
import com.lyf.scm.admin.domain.remote.item.facade.ItemCoreFacade;
import com.lyf.scm.admin.domain.remote.network.facade.NetworkFacade;
import com.lyf.scm.admin.domain.remote.stock.facade.StockFacade;
import com.lyf.scm.admin.domain.service.OutService;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.SkuUnitTypeEnum;
import com.lyf.scm.common.model.SalesPlanSelectDTO;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 李兵兵
 * @date 2020/08/12
 */
@Service
public class OutServiceImpl implements OutService {
    @Resource
    private ItemCoreFacade itemCoreFacade;

    @Resource
    private BaseDataFacade baseDataFacade;

    @Resource
    private NetworkFacade networkFacade;

    @Resource
    private StockFacade stockFacade;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public List<CategoryBaseInfoDTO> getLowerLevelCategoryByParentId(Long parentId) {
        return itemCoreFacade.getLowerLevelCategoryByParentId(parentId);
    }

    @Override
    public List<CategoryBaseInfoDTO> categoryListByCategoryCodes(List<String> stringList) {
        return itemCoreFacade.categoryListByCategoryCodes(stringList);
    }

    @Override
    public List<SalesPlanSelectDTO> skuListByCategoryId(Long categoryId, Integer pageNum, Integer pageSize) {
        PageInfo<SkuInfoDTO> response = itemCoreFacade.skuListByCategoryId(categoryId, pageNum, pageSize);
        List<SalesPlanSelectDTO> list = new ArrayList<>();
        //品类最小到第四级，所以sku的level为5
        if (ObjectUtil.isNotEmpty(response.getList())) {
            response.getList().forEach(item -> {
                SalesPlanSelectDTO selectDTO = new SalesPlanSelectDTO();
                selectDTO.setLevel(CommonConstants.CATEGORY_LEVEL_FOUR);
                selectDTO.setCode(item.getSkuCode());
                selectDTO.setName(item.getSkuCode() + "/" + item.getName());
                list.add(selectDTO);
            });
        }
        return list;
    }

    @Override
    public List<CategoryBaseInfoDTO> getCategoryListByLevel(Integer level) {
        return itemCoreFacade.getCategoryListByLevel(level);
    }

    /**
     * 根据Level等级获取区域信息
     *
     * @param level
     * @return
     */
    @Override
    public PageInfo<AreaDTO> searchAreaByLevels(List<Integer> level) {
        return baseDataFacade.getAreaByLevels(level, null, null);
    }

    /**
     * 据parentCode获取所有下级根
     *
     * @param parentCode
     * @return
     */
    @Override
    public List<SalesPlanSelectDTO> searchByParentCode(String parentCode) {
        return baseDataFacade.getSubAreaCode(parentCode);
    }

    /**
     * 根据当前日期获取前三周后十四周公立节假日（对计划接口）
     *
     * @param startDate
     * @return {@link List< DateLabelDTO >}
     **/
    @Override
    public List<DateLabelDTO> getDateLabels(Date startDate) {
        return networkFacade.getDateLabels(startDate);
    }

    @Override
    public List<UnitTypeDTO> listUnitType() {
        SkuUnitTypeEnum[] values = SkuUnitTypeEnum.values();
        List<UnitTypeDTO> typeDTOList = new ArrayList<>();
        for (SkuUnitTypeEnum value : values) {
            UnitTypeDTO unitTypeDTO = new UnitTypeDTO();
            unitTypeDTO.setUnitType(value.getUnitType());
            unitTypeDTO.setUnitName(value.getUnitName());
            typeDTOList.add(unitTypeDTO);
        }
        return typeDTOList;
    }

    /**
     * 查询所有公司信息
     *
     * @return {@link List< SaleOrgDTO >}
     */
    @Override
    public List<SalesPlanSelectDTO> listSaleOrg() {
        List<SaleOrgDTO> saleOrgList = baseDataFacade.listSaleOrg();
        List<SalesPlanSelectDTO> salesPlanSelectList = new ArrayList<>();
        saleOrgList.forEach(item -> {
            SalesPlanSelectDTO salesPlanSelect = new SalesPlanSelectDTO();
            salesPlanSelect.setId(item.getId());
            salesPlanSelect.setCode(item.getOrgCode());
            salesPlanSelect.setName(item.getOrgName());
            salesPlanSelectList.add(salesPlanSelect);
        });
        return salesPlanSelectList;
    }

    @Override
    public List<SalesPlanSelectDTO> parentChannel(String parentChannel) {
        List<ChannelDTO> channelDTOS = baseDataFacade.queryByParentChannel(parentChannel);
        return getSalePlanSelectDTO(channelDTOS);
    }

    @Override
    public List<SalesPlanSelectDTO> queryByLevel(Integer level) {
        List<ChannelDTO> channelByLevel = baseDataFacade.getChannelByLevel(level);
        return getSalePlanSelectDTO(channelByLevel);
    }

    @Override
    public List<SalesPlanSelectDTO> listStore(SearchStoreParamDTO storeParamDTO,
                                              Integer pageNum, Integer pageSize) {
        PageInfo<StoreDTO> response = baseDataFacade.selectStoreByAreaCode(storeParamDTO, pageNum, pageSize);
        List<SalesPlanSelectDTO> selectDTOS = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(response.getList())) {
            response.getList().forEach(item -> {
                SalesPlanSelectDTO selectDTO = new SalesPlanSelectDTO();
                selectDTO.setCode(item.getCode());
                selectDTO.setName(item.getCode());
                selectDTO.setLevel(CommonConstants.AREA_LEVEL_FOUR);
                selectDTOS.add(selectDTO);
            });
        }
        return selectDTOS;
    }

    /**
     * 根据角色获取最高级区域信息
     *
     * @param
     * @return {@link List<AreaDTO>}
     **/
    @Override
    public List<AreaDTO> searchAreaByRole() {
        //TODO 模拟该角色的区域（石家庄市）
        List<AreaDTO> list = new ArrayList<>();
        AreaDTO areaDTO = new AreaDTO();
        areaDTO.setLevel(1);
        areaDTO.setName("河北省");
        areaDTO.setCode("130000");
        areaDTO.setParentCode("100000");
        areaDTO.setId(4L);
        list.add(areaDTO);
        return list;
    }

    /**
     * 通过类型查询仓库
     *
     * @param realWarehouseType
     * @return {@link List<StoreDTO>}
     **/
    @Override
    public List<StoreDTO> queryFactoryByRwType(Integer realWarehouseType) {
        return stockFacade.queryFactoryByRwType(realWarehouseType);
    }

    /**
     * 处理数据
     */
    private List<SalesPlanSelectDTO> getSalePlanSelectDTO(List<ChannelDTO> channelDTOS) {
        List<SalesPlanSelectDTO> selectDTOS = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(channelDTOS)) {
            channelDTOS.forEach(item -> {
                SalesPlanSelectDTO selectDTO = new SalesPlanSelectDTO();
                selectDTO.setId(item.getId());
                selectDTO.setCode(item.getChannel());
                selectDTO.setName(item.getChannelName());
                selectDTO.setLevel(item.getLevel());
                selectDTOS.add(selectDTO);
            });
        }
        return selectDTOS;
    }

    @Override
    public List<AreaDTO> searchAllAreaList() {
        String key = "SCM_PLAN_ALLAREALIST";
        List<AreaDTO> data = (List<AreaDTO>) redisTemplate.opsForValue().get(key);
        if (data != null) {
            return data;
        }
        List<AreaDTO> list = new ArrayList<>();
        int pageNum = 1;
        int pageSize = 500;
        List<Integer> levelList = Arrays.asList(0,1, 2, 3);
        PageInfo<AreaDTO> pageInfo = baseDataFacade.getAreaByLevels(levelList, pageNum, pageSize);
        while (pageInfo != null && pageInfo.getSize() > 0 && pageNum <= pageInfo.getPages()) {
            list.addAll(pageInfo.getList());
            pageInfo = baseDataFacade.getAreaByLevels(levelList, ++pageNum, pageSize);
        }
        if (list.size() == 0) {
            return list;
        }

        // 取门店
        Set<String> countryCodeList = list.stream().filter(dto -> dto.getLevel() == 3).map(AreaDTO::getCode).collect(Collectors.toSet());
        List<AreaDTO> list2 = new ArrayList<>();
        int pageNum2 = 1;
        int pageSize2 = 500;
        List<String> params = new ArrayList<>(countryCodeList);
        PageInfo<StoreDTO> pageInfo2 = baseDataFacade.selectStoreByDistrictCode(params, pageNum2, pageSize2);
        while (pageInfo2 != null && pageInfo2.getSize() > 0 && pageNum2 <= pageInfo2.getPages()) {
            List<StoreDTO> storeDTOList = pageInfo2.getList();
            for (StoreDTO storeDTO : storeDTOList) {
                if ("拆店".equals(storeDTO.getDesc())) {
                    continue;
                }
                AreaDTO areaDTO = new AreaDTO();
                areaDTO.setCode(storeDTO.getCode());
                areaDTO.setLevel(4);
                areaDTO.setName(storeDTO.getName());
                areaDTO.setParentCode(storeDTO.getDistrictCode());
                list2.add(areaDTO);
            }
            pageInfo2 = baseDataFacade.selectStoreByDistrictCode(params, ++pageNum2, pageSize2);
        }

        // 把门店也加进来
        list.addAll(list2);

        redisTemplate.opsForValue().set(key, list, Duration.ofMinutes(30));
        return list;
    }
}
